﻿using System;
using System.Collections.Generic;
using ICSharpCode.AvalonEdit.Rendering;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using System.Windows.Input;
using System.Windows;
using System.Windows.Controls;
using System.IO;
using System.Linq;
using JmShared;
using GalaSoft.MvvmLight.Messaging;
using JiveMessenger.Models;
using JiveMessenger.User;
using JiveMessenger.Utilities;
using System.Windows.Media.Imaging;
using JiveMessenger.ViewModels;
using NLog;

namespace JiveMessenger.AvalonEdit
{
    /// <summary>
    /// VisualLineElement implementation for embedded images.
    /// </summary>
    public class ImageElement : VisualLineElement
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        private readonly string _imageFileName;
        private readonly BitmapSource _image;
        private readonly string _key;
        private IClient _currentClient;
        public ImageElement(BitmapSource image, IClient currentClient, string imageFileName, string key, int documentLength)
            : base(1, documentLength)
        {
            if (String.IsNullOrEmpty(imageFileName))
                throw new ArgumentNullException("imageFileName");
            if (image == null)
                throw new ArgumentNullException("image");
            this._imageFileName = imageFileName;
            this._image = image;
            this._key = key;
            this._currentClient = currentClient;


        }

        public override TextRun CreateTextRun(int startVisualColumn, ITextRunConstructionContext context)
        {
            return new ImageTextRun(this._image, TextRunProperties);
        }

        private void mi_Click(object sender, RoutedEventArgs e)
        {

            MenuItem mi = (MenuItem)sender;
            Messenger.Default.Send(new NotificationMessage<IEmoticon>(new JiveCustomEmoticonModel { EmoticonPath = _imageFileName, EmoticonShortcut = _key }, "AddEmoticon"));
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            TextView tw = e.OriginalSource as TextView;
            //  base.OnMouseDown(e);
            if (e.Handled
                || e.RightButton != MouseButtonState.Pressed
                || this._key == "<spacer>"
                || this._key == "<line>"
                || this._key == "<s_music>"
                || this._key == "</s_music>"
                || this._key == "<w_music>"
                || this._key == "</w_music>"
                || tw == null)
            {
                base.OnMouseDown(e);
                return;
            }
            try
            {
                //if (tw.ContextMenu == null)
                //    tw.ContextMenu = new ContextMenu();
                ContextMenu menu = new ContextMenu();//tw.ContextMenu;
                menu.Items.Clear();
                MenuItem mi = new MenuItem { Header = "Add" };
                mi.Click += this.mi_Click;
                menu.Items.Add(mi);
                //mi.Tag = this._imageFileName;
                //  tw.Tag = mi;
                if (this._currentClient.GetEmoticons(_currentClient.CurrentUserInfo.UserID, true, true, false).Values.Any(emoticon => emoticon.EmoticonPath == this._imageFileName))
                {
                    mi.IsEnabled = false;
                }
                menu.IsOpen = true;
                e.Handled = true;
            }
            catch (Exception ex)
            {
                Logger.ErrorException("Exception in image mousedown", ex);
            }
        }

        sealed class ImageTextRun : TextEmbeddedObject
        {
            readonly BitmapSource _image;
            readonly TextRunProperties _properties;

            public ImageTextRun(BitmapSource image, TextRunProperties properties)
            {
                this._image = image;
                this._properties = properties;
            }

            public override LineBreakCondition BreakBefore
            {
                get { return LineBreakCondition.BreakPossible; }
            }

            public override LineBreakCondition BreakAfter
            {
                get { return LineBreakCondition.BreakPossible; }
            }

            public override bool HasFixedSize
            {
                get { return true; }
            }

            public override CharacterBufferReference CharacterBufferReference
            {
                get { return new CharacterBufferReference(); }
            }

            public override int Length
            {
                get { return 1; }
            }

            public override TextRunProperties Properties
            {
                get { return this._properties; }
            }

            public override TextEmbeddedObjectMetrics Format(double remainingParagraphWidth)
            {
                return new TextEmbeddedObjectMetrics(this._image.Width, this._image.Height, this._image.Height);
            }

            public override Rect ComputeBoundingBox(bool rightToLeft, bool sideways)
            {
                return new Rect(0, 0, this._image.Width, this._image.Height);
            }

            public override void Draw(DrawingContext drawingContext, Point origin, bool rightToLeft, bool sideways)
            {
                drawingContext.DrawImage(this._image, new Rect(origin.X, origin.Y - this._image.Height, this._image.Width, this._image.Height));
            }
        }
    }
}
